package net.stratusprogramming.school.Game.Framework.System;

import java.io.File;


import com.almworks.sqlite4java.SQLiteConnection;
import com.almworks.sqlite4java.SQLiteException;
import com.almworks.sqlite4java.SQLiteStatement;

public class SaveMgr {
	
	private SQLiteConnection db;

	/**
	 * Determines if there is a save to load
	 * 
	 * @return true if there is a save to load, else false
	 */
	
	public boolean saveAvailable() {
		File saveFile = new File("res/saves/save.sql");
		return (saveFile.exists() && saveFile.canRead() && saveFile.canWrite());
	}
	
	public void loadSave() {
		if(!saveAvailable()) {
			Logger.logln("System-save", "No save available... copying base.sql");			
			MscFunctions.binCopy(new File("res/saves/base.sql"),  new File("res/saves/save.sql"));
		}
		
		db = new SQLiteConnection(new File("res/saves/save.sql"));
		
		boolean loaded;
		try {
			db.open(false);
			loaded = true;
		} catch (SQLiteException e) {
			e.printStackTrace();
			loaded = false;
		}
		
		// load everything in world
		
		if(loaded) {
			Logger.logln("System-save", "loading save...");	
			InstanceMgr.world.load();
			Logger.logln("System-save", "save loaded!");	
		} else Logger.logln("System-save", "ERROR: Could not load save");	
		
		db.dispose();
	}

	public void save() {
		File saveFile = new File("res/saves/save.sql");		
		// connect to sqlite
		db = new SQLiteConnection(new File("res/saves/save.sql"));
		boolean loaded;
		try {
			db.open(false);
			loaded = true;
		} catch (SQLiteException e) {
			e.printStackTrace();
			loaded = false;
		}
		
		// save everything in world
		if(loaded) {
			Logger.logln("System-save", "saving...");	
			InstanceMgr.world.save();
			Logger.logln("System-save", "saved!");	
		} else Logger.logln("System-save", "ERROR: Could not save");	;
		
		db.dispose();
	}

	
	public int getSettingInt(String name) { return Integer.parseInt(getSetting(name)); };
	public double getSettingDouble(String name) { return Double.parseDouble(getSetting(name)); };
	public float getSettingFloat(String name) { return Float.parseFloat(getSetting(name)); };
	public long getSettingLong(String name) { return Long.parseLong(getSetting(name)); };
	public short getSettingShort(String name) { return Short.parseShort(getSetting(name)); };
	public boolean getSettingBoolean(String name) { return Boolean.parseBoolean(getSetting(name)); };
	
	public String getSetting(String name) {
		String ret = "";
		if(db.isOpen()) {
			SQLiteStatement st = null;
			try {
				st = db.prepare("SELECT * FROM settings WHERE name = ?");
				st.bind(1, name);
				if(st.step()) {
					ret = st.columnString(2);
				} else {
					System.out.println("No entry for "+name);
				}
				
			} catch (SQLiteException e) {
				e.printStackTrace();
			} finally {
				if(st != null && !st.isDisposed()) st.dispose();
			}
		}
		
		return ret;
	}
	
	public boolean hasSetting(String name) {
		if(db.isOpen()) {
			SQLiteStatement st = null;
			try {
				st = db.prepare("SELECT * FROM settings WHERE name = ?");
				st.bind(1, name);
				if(st.step()) {
					return true;
				} else return false;
			} catch(Exception e) { return false; }
		} else return false;
	}
	
	public <T> void setSetting(String name, T value) {
		if(db.isOpen()) {
			SQLiteStatement st = null;
			try {
				if(hasSetting(name)) {
					st = db.prepare("UPDATE settings SET value = ? WHERE name = ?");
					st.bind(1, ""+value);
					st.bind(2, name);
					st.step();
				} else {
					st = db.prepare("INSERT INTO settings (name, value) VALUES(?, ?)");
					st.bind(1, name);
					st.bind(2, ""+value);
					st.step();
				}
			} catch (SQLiteException e) {
				e.printStackTrace();
			} finally {
				if(st != null && !st.isDisposed()) st.dispose();
			}
		}
	}
	
	/**
	 * @return the db
	 */
	public SQLiteConnection getDb() {
		return db;
	}
	
	
}
